﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
using Proggy.Web.Cms.PropertyTypes;
using Proggy.Web.Cms.ContentModel;
using Proggy.Web.Cms.Core.Configuration.ConfigObjects;
using System.Text.RegularExpressions;

namespace Proggy.Web.Cms.Core.PropertyTypes
{
    /// <summary>
    /// Property type enabling a characting string with a char limt
    /// </summary>
    [PropertyType("Text string (char limited)", "~/Areas/ProggyCore/Views/EditorPartials/CharLimitedTextStringEditor.cshtml", RequiredConfigObjectType = typeof(CharLimitedTextStringConfigObject))]
    public class CharLimitedTextString : ConfigurablePropertyTypeBase, IValidatablePropertyType
    {
        /// <summary>
        /// Constructor
        /// </summary>
        public CharLimitedTextString()
        {
            // check
            if (string.IsNullOrEmpty(this.SavedValue))
            {
                this.SavedValue = "";
            }
        }

        /// <summary>
        /// The value of the text string
        /// </summary>
        public string SavedValue { get; set; }

        /// <summary>
        /// Checks if property is valid based on values and validation context
        /// </summary>
        /// <param name="vContext"></param>
        /// <returns></returns>
        public Tuple<bool, string> GetIsValid(ValidationContext vContext, ContentModelPropertyTypeAttribute attr)
        {
            // get config
            var config = this.GetConfigObjectInValidationContext<CharLimitedTextStringConfigObject>(vContext, attr);

            // set
            if (this.SavedValue == null)
            {
                this.SavedValue = string.Empty;
            }

            // check null
            if (this.SavedValue==string.Empty && config.Minimum == 0)
            {
                return new Tuple<bool, string>(true, "");
            }

            // check regex
            foreach (var matchPattern in config.RegexMatchPatterns)
            {
                if (!Regex.IsMatch(SavedValue, matchPattern.RegexMatchPattern))
                {
                    return new Tuple<bool, string>(false, "Invalid text entered: " + matchPattern.IfNotMatchErrorMessage);
                }
            }

            // check characters            
            foreach (var exChar in config.ExcludedCharacters)
            {
                if (SavedValue.Contains(exChar))
                {
                    return new Tuple<bool, string>(false, "Invalid character entered (\"" + exChar + "\")");
                }
            }

            // check limit
            if (config.Limit > 0 && SavedValue.Length > config.Limit)
            {
                return new Tuple<bool, string>(false, "Character limit exceeded");
            }

            if (SavedValue.Length < config.Minimum)
            {
                return new Tuple<bool, string>(false, "A minimum of " + config.Minimum + " characters are required.");
            }

            // ok
            return new Tuple<bool, string>(true, null);

        }
    }
}
